package com.wtwd.campus.jdzc.controller;

import com.alibaba.fastjson.JSONObject;
import com.wtwd.campus.jdzc.common.Constant;
import com.wtwd.campus.jdzc.common.RespCode;
import com.wtwd.campus.jdzc.common.RespEntity;
import com.wtwd.campus.jdzc.entity.DeviceInfo;
import com.wtwd.campus.jdzc.service.*;
import com.wtwd.campus.service.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author: ldaoliang
 * @DateTime: 2022/2/14 16:30
 * @Description: 通话记录，告警记录等
 */

@RestController
@RequestMapping("/jdzc/record")
public class JdzcRecordController {

    private static final Logger logger = LoggerFactory.getLogger(JdzcUserController.class);


    @Autowired
    private JdzcLogService jdzcLogService;

    @Autowired
    private JdzcDeviceInfoService jdzcDeviceInfoService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private JdzcStudentService jdzcStudentService;

    @Autowired
    private JdzcInformationService jdzcinformationService;

    @Autowired
    private JdzcNotificationService jdzcNotificationService;

    @Autowired
    private AuthService authService;

    /**
     * 获取通话记录
     *
     * @param jsonObject
     * @param request
     * @return
     */
    @PostMapping("/getCallRecord")
    public RespEntity getCallRecord(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer stuId = jsonObject.getInteger("stuId");
        Integer num = jsonObject.getInteger("num");
        Boolean authStudent = authService.authStudentOrgCode(stuId, Constant.jdzcOrgCode, userId);
        if (!authStudent){
            return new RespEntity(RespCode.NO_PERMISSION);
        }
        if (stuId==null||num==null){
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        logger.info("getCallRecord : stuId = {}" + stuId.toString());
        //根据学生id获取通话记录
        List<Map<String, Object>> callList = jdzcLogService.getCallRecordByStuId(stuId, num);
        return new RespEntity(RespCode.SUCCESS, callList);
    }

    /**
     * 获取一个学生的所有存在的告警类型（沃特平台）
     */

    @PostMapping("/getWarningType")
    public RespEntity getWarningTypeWater(@RequestBody JSONObject jsonObject,HttpServletRequest request){
        Integer stuId = jsonObject.getInteger("stuId");
        logger.info("getWarningTypeWater : stuId = {}" + stuId.toString());
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Boolean authStudent = authService.authStudentOrgCode(stuId, Constant.jdzcOrgCode, userId);
        if (!authStudent){
            return new RespEntity(RespCode.NO_PERMISSION);
        }
        //根据学生id获取该学生的所有存在的告警类型
        List<Map<String, Object>> warnTypeList = jdzcLogService.getWarningTypeByStuId(stuId);
        //根据学生id查询设备
        DeviceInfo deviceInfo = jdzcDeviceInfoService.getDeviceInfoByStuId(stuId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.STUDENT_NOT_BIND_DEVICE);
        }
        //去重，如果有一个类型有两笔相同时间的告警类型，取id最大的那个
        List<Optional<Map<String, Object>>> collect = warnTypeList.stream().collect(Collectors.groupingBy(e -> e.get("warning_type"))).values().stream().map(e -> {
            return e.stream().max((e1, e2) -> (Integer) e1.get("id") > (Integer) e2.get("id") ? 1 : -1);
        }).collect(Collectors.toList());
        List<Map<String, Object>> result = new ArrayList<>();
        List<Map<String, Object>> fenceWarn = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //查询告警类型消息状态
        Map<String, Object> isNewMap = redisService.getHash(Constant.WARN_TYPE_IS_NEW_JDZC.concat(stuId.toString()));
        boolean flag = isNewMap == null ? true : false;
        //拼凑返回的信息
        collect.stream().forEach(e -> {
            Map<String, Object> map = e.get();
            Integer type = (Integer) map.get("warning_type");
            Long time = (Long) map.get("warning_time");
            map.put("time", sdf.format(new Date((Long) map.get("warning_time"))));
            Long oldTime = 0l;
            if (type == Constant.SOS_WARNING_TYPE) {
                map.put("warnName", "SOS提醒");
                map.put("content", "您的设备".concat("于").concat((String) map.get("address")).concat("拨打SOS号码"));
                if (!flag && isNewMap.get("sos") != null) {
                    oldTime = (Long) isNewMap.get("sos");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                //如果是有新消息，则查询新消息数目
                if ((boolean) map.get("isNew")) {
                    //根据上次查看时间和本次点击时间查询新消息数目
                    int i = jdzcLogService.selectCountByTypeAndTime(deviceInfo.getDeviceId(), type, oldTime);
                    map.put("newNum", i);
                }
                result.add(map);
            } else if (type == Constant.LOW_BATTERY_WARNING_TYPE) {
                map.put("warnName", "低电量提醒");
                map.put("content", "您的设备".concat("电量不足15%，请及时充电"));
                if (!flag && isNewMap.get("lowBattery") != null) {
                    oldTime = (Long) isNewMap.get("lowBattery");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                //如果是有新消息，则查询新消息数目
                if ((boolean) map.get("isNew")) {
                    //根据上次查看时间和本次点击时间查询新消息数目
                    int i = jdzcLogService.selectCountByTypeAndTime(deviceInfo.getDeviceId(), type, oldTime);
                    map.put("newNum", i);
                }
                result.add(map);
            } else if (type == Constant.ENTER_FENCE_WARNING_TYPE) {
                map.put("warnName", "围栏提醒");
                String fenceName = map.get("fence_name") == null ? "" : (String) map.get("fence_name");
                map.put("content", "您的设备".concat("进入").concat(fenceName).concat("围栏"));
                map.put("warning_type", 5);
                if (!flag && isNewMap.get("fence") != null) {
                    oldTime = (Long) isNewMap.get("fence");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                //如果是有新消息，则查询新消息数目
                if ((boolean) map.get("isNew")) {
                    //根据上次查看时间和本次点击时间查询新消息数目
                    int i = jdzcLogService.selectCountByTypeAndTime(deviceInfo.getDeviceId(), type, oldTime);
                    map.put("newNum", i);
                }
                result.add(map);
            } else if (type == Constant.LEFT_WARNING_TYPE) {
                map.put("warnName", "围栏提醒");
                String fenceName = map.get("fence_name") == null ? "" : (String) map.get("fence_name");
                map.put("content", "您的设备".concat("出").concat(fenceName).concat("围栏"));
                map.put("warning_type", 5);
                if (!flag && isNewMap.get("fence") != null) {
                    oldTime = (Long) isNewMap.get("fence");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                //如果是有新消息，则查询新消息数目
                if ((boolean) map.get("isNew")) {
                    //根据上次查看时间和本次点击时间查询新消息数目
                    int i = jdzcLogService.selectCountByTypeAndTime(deviceInfo.getDeviceId(), type, oldTime);
                    map.put("newNum", i);
                }
                result.add(map);
            } else if (type == Constant.SHUT_DOWN_WARNING_TYPE) {
                map.put("warnName", "关机提醒");
                map.put("content", "您的设备".concat("已关机"));
                if (!flag && isNewMap.get("shutdown") != null) {
                    oldTime = (Long) isNewMap.get("shutdown");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                //如果是有新消息，则查询新消息数目
                if ((boolean) map.get("isNew")) {
                    //根据上次查看时间和本次点击时间查询新消息数目
                    int i = jdzcLogService.selectCountByTypeAndTime(deviceInfo.getDeviceId(), type, oldTime);
                    map.put("newNum", i);
                }
                result.add(map);
            } else if (type == Constant.POWER_ON_WARNING_TYPE) {
                map.put("warnName", "开机提醒");
                map.put("content", "您的设备".concat("已开机"));
                if (!flag && isNewMap.get("powerOn") != null) {
                    oldTime = (Long) isNewMap.get("powerOn");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                //如果是有新消息，则查询新消息数目
                if ((boolean) map.get("isNew")) {
                    //根据上次查看时间和本次点击时间查询新消息数目
                    int i = jdzcLogService.selectCountByTypeAndTime(deviceInfo.getDeviceId(), type, oldTime);
                    map.put("newNum", i);
                }
                result.add(map);
            }
        });
        //合并出围栏和入围栏信息
        List<Optional<Map<String, Object>>> result2 = result.stream().collect(Collectors.groupingBy(e -> e.get("warning_type"))).values().stream().map(e -> {
            return e.stream().max((e1, e2) -> (Integer) e1.get("id") > (Integer) e2.get("id") ? 1 : -1);
        }).collect(Collectors.toList());
/*        //结果进行固定位置编排
        List<Map<String, Object>> list = changePlace(result2);*/
        //根据学生id获取学校id和班级id
        Map<String, Object> map = jdzcStudentService.getSchoolIdAndClassIdByStuId(stuId);
        Integer classId = (Integer) map.get("classes_id");
        Integer schoolId = (Integer) map.get("id");
        //查询出最新的咨询或者通知
        Long time1 = jdzcinformationService.getBiggestTimeBySchoolId(schoolId);
        Long time2 = jdzcNotificationService.getLatestNotificationTimeByClassId(classId);
        if (time1 != null || time2 != null) {
            Map<String, Object> newsMap = new HashMap<>();
            newsMap.put("warnName", "校园通知");
            newsMap.put("content", "您有一条新的校园通知，请点击查看");
            newsMap.put("warning_type", 0);
            if (time1 != null && time2 == null) {
                newsMap.put("warning_time", time1);
            } else if (time1 == null && time2 != null) {
                newsMap.put("warning_time", time2);
            } else {
                /*  newsMap.put("warning_time", sdf.format(new Date(time1 > time2 ? time1 : time2)));*/
                newsMap.put("warning_time", time1 > time2 ? time1 : time2);
            }
            if (!flag && isNewMap.get("school") != null) {
                Long oldTime = (Long) isNewMap.get("school");
                boolean isNew = (Long) newsMap.get("warning_time") > oldTime ? true : false;
                newsMap.put("isNew", isNew);
            } else {
                newsMap.put("isNew", true);
            }
            result2.add(Optional.of(newsMap));
        }
        return new RespEntity(RespCode.SUCCESS, result2);
    }



    /**
     * 获取告警记录
     *
     * @param stuId
     * @param request
     * @return
     */
    @GetMapping("/getWarningList/{stuId}/{warnType}/{num}")
    public RespEntity getWarningList(@PathVariable Integer stuId, @PathVariable Integer warnType,
                                     @PathVariable Integer num, HttpServletRequest request) {
        logger.info("getWarningList : stuId = {},warnType = {}", stuId.toString(), warnType.toString());
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Boolean authStudent = authService.authStudentOrgCode(stuId, Constant.jdzcOrgCode, userId);
        if (!authStudent){
            return new RespEntity(RespCode.NO_PERMISSION);
        }
        //根据学生id和类型查询告警记录
        List<Map<String, Object>> warnList = jdzcLogService.getWarningListByStuIdAndType(stuId, warnType, num);
        warnList.stream().forEach(e -> {
            Integer type = (Integer) e.get("warning_type");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            e.put("time", sdf.format(new Date((Long) e.get("warning_time"))));
            if (type == Constant.SOS_WARNING_TYPE) {
                e.put("warnName", "SOS提醒");
                e.put("content", "您的设备".concat("于").concat((String) e.get("address")).concat("拨打SOS号码"));
            } else if (type == Constant.LOW_BATTERY_WARNING_TYPE) {
                e.put("warnName", "低电量提醒");
                e.put("content", "您的设备".concat("电量不足15%，请及时充电"));
            } else if (type == Constant.ENTER_FENCE_WARNING_TYPE) {
                e.put("warnName", "围栏提醒");
                String fenceName = e.get("fence_name") == null ? "" : (String) e.get("fence_name");
                e.put("content", "您的设备".concat("进入").concat(fenceName).concat("围栏"));
                e.put("warning_type", 5);
            } else if (type == Constant.LEFT_WARNING_TYPE) {
                e.put("warnName", "围栏提醒");
                String fenceName = e.get("fence_name") == null ? "" : (String) e.get("fence_name");
                e.put("content", "您的设备".concat("出").concat(fenceName).concat("围栏"));
                e.put("warning_type", 5);
            } else if (type == Constant.SHUT_DOWN_WARNING_TYPE) {
                e.put("warnName", "关机提醒");
                e.put("content", "您的设备".concat("已关机"));
            } else if (type == Constant.POWER_ON_WARNING_TYPE) {
                e.put("warnName", "开机提醒");
                e.put("content", "您的设备".concat("已开机"));
            }
        });
        return new RespEntity(RespCode.SUCCESS, warnList);
    }



    /**
     * 根据类型和时间去更新一个类型是否是最新记录
     *
     * @param type
     * @param isNew
     * @param time
     * @param request
     * @return
     */
    @GetMapping("/setMessIsNew/{type}/{isNew}/{time}/{stuId}")
    public RespEntity setMessIsNew(@PathVariable Integer type, @PathVariable Boolean isNew,
                                   @PathVariable Long time, @PathVariable Integer stuId,
                                   HttpServletRequest request) {
        logger.info("setMessIsNew : type = {},isNew = {},time = {}", type.toString(), isNew.toString(), time.toString());
        //鉴别该拥用户是否有权操作该学生
        String token = request.getHeader(Constant.HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        Boolean authStudent = authService.authStudent(stuId, Constant.jdzcOrgCode, userId);
        if (!authStudent){
            return new RespEntity(RespCode.NO_PERMISSION);
        }
        if (isNew) {
            //如果是新消息则修改存储时间
            String key = Constant.WARN_TYPE_IS_NEW_JDZC.concat(stuId.toString());
            boolean b = redisService.hasKey(key);
            if (!b) {
                Map<String, Object> map = new HashMap<>();
                String name = "";
                if (type == Constant.LOW_BATTERY_WARNING_TYPE) {
                    name = "lowBattery";
                } else if (type == Constant.SOS_WARNING_TYPE) {
                    name = "sos";
                } else if (type == 5) {
                    name = "fence";
                } else if (type == Constant.POWER_ON_WARNING_TYPE) {
                    name = "powerOn";
                } else if (type == Constant.SHUT_DOWN_WARNING_TYPE) {
                    name = "shutdown";
                } else if (type == 0) {
                    name = "school";
                }
                map.put(name, time);
                redisService.setHash2(key, map, 0, TimeUnit.SECONDS);
            } else {
                Map<String, Object> map = redisService.getHash(key);
                if (type == Constant.LOW_BATTERY_WARNING_TYPE) {
                    map.put("lowBattery", time);
                } else if (type == Constant.SOS_WARNING_TYPE) {
                    map.put("sos", time);
                } else if (type == 5) {
                    map.put("fence", time);
                } else if (type == Constant.POWER_ON_WARNING_TYPE) {
                    map.put("powerOn", time);
                } else if (type == Constant.SHUT_DOWN_WARNING_TYPE) {
                    map.put("shutdown", time);
                } else if (type == 0) {
                    map.put("school", time);
                }
                redisService.setHash2(key, map, 0, TimeUnit.SECONDS);
            }
        }
        return new RespEntity(RespCode.SUCCESS);
    }




    /**
     * 获取用户id
     *
     * @param request
     * @return
     */
    public Integer getUserId(HttpServletRequest request) {
        //获取用户id
        String token = request.getHeader(Constant.HEADER_TOKEN_KEY);
        if (token.equals("aaab")) {
            return 3;
        }
        String redisUserId = redisService.getValue(token);
        if (org.apache.commons.lang.StringUtils.isBlank(redisUserId)) {
            return 0;
        }
        Integer userId = Integer.parseInt(redisUserId);
        return userId;
    }




}
